import os

from PyQt5.QtCore import Qt, QTimer, pyqtSignal
from PyQt5.QtGui import (QPixmap, QIcon)
from PyQt5.QtWidgets import (QMainWindow, QLabel,
                             QDesktopWidget, QSystemTrayIcon, QMenu)

from utils.webp_player import WebpPlayer

# 状态图片
STATE_IMAGES = {
    'idle': 'assets/icon.png',
    'listening': 'assets/icon.png',
    'thinking': 'assets/icon.png',
    'speaking': 'assets/speak_icon.webp'  # 修改为WebP动画文件
}


class DesktopPetWindow(QMainWindow):
    # 添加信号用于线程安全的状态更新
    stateChanged = pyqtSignal(str)
    
    def __init__(self):
        super().__init__()

        # 初始化宠物状态
        self.old_pos = None
        self.current_state = 'idle'
        self.dragging = False

        # 连接信号
        self.stateChanged.connect(self.set_pet_state)

        # 创建宠物窗口
        self.setup_window()

        # 创建宠物状态标签
        self.pet_label = QLabel(self)
        self.pet_label.setAlignment(Qt.AlignCenter)
        
        # 添加WebP播放器
        self.webp_player = WebpPlayer(self)  # 创建WebP播放器实例，设置父窗口

        # 设置初始状态
        self.set_pet_state('idle')

        # 启动状态更新定时器
        self.state_timer = QTimer()
        self.state_timer.timeout.connect(self.update_state)
        self.state_timer.start(100)

        # 启动语音交互线程
        self.voice_worker = None

        print("🚀 桌面宠物已启动！点击宠物启动语音交互")

    def setup_window(self):
        """设置窗口属性"""
        # 无边框窗口
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)

        # 设置窗口大小
        self.resize(200, 200)

        # 使窗口始终在最前面
        self.setWindowOpacity(0.95)

        # 设置背景透明
        self.setAttribute(Qt.WA_TranslucentBackground)

        # 设置窗口位置（在屏幕中心）
        self.center_window()

        # 创建系统托盘
        self.create_tray_icon()

    def center_window(self):
        """将窗口设置在屏幕中心"""
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) // 2, 
                  (screen.height() - size.height()) // 2)

    def get_icon(self, state):
        """获取指定状态的图标"""
        pixmap = QPixmap(STATE_IMAGES.get(state, STATE_IMAGES['idle']))
        return QIcon(pixmap.scaled(16, 16, Qt.KeepAspectRatio, Qt.SmoothTransformation))

    def create_tray_icon(self):
        """创建系统托盘"""
        # 创建系统托盘图标实例，传入当前窗口作为父对象
        self.tray_icon = QSystemTrayIcon(self)
        # 设置托盘图标为宠物idle状态对应的图标
        pixmap = QPixmap('assets/tubiao.png')
        # 如果图标文件不存在，创建一个默认图标
        if pixmap.isNull():
            pixmap = QPixmap(32, 32)
            pixmap.fill(Qt.blue)
        # 使用固定尺寸并确保高质量缩放
        pixmap = pixmap.scaled(32, 32, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.tray_icon.setIcon(QIcon(pixmap))

        # 创建托盘菜单
        tray_menu = QMenu()
        show_action = tray_menu.addAction("显示宠物")
        show_action.triggered.connect(self.show)
        hide_action = tray_menu.addAction("隐藏宠物")
        hide_action.triggered.connect(self.hide)
        exit_action = tray_menu.addAction("退出")
        exit_action.triggered.connect(self.close)

        # 将托盘菜单设置到托盘图标
        self.tray_icon.setContextMenu(tray_menu)

        # 显示托盘图标
        self.tray_icon.show()

        # 双击托盘图标显示窗口
        self.tray_icon.activated.connect(self.on_tray_icon_activated)

    def on_tray_icon_activated(self, reason):
        """处理托盘图标被双击的事件"""
        # 双击显示/隐藏窗口
        if reason == QSystemTrayIcon.DoubleClick:
            if self.isVisible():
                self.hide()
            else:
                self.show()
                self.activateWindow()

    def set_pet_state(self, state):
        """设置宠物状态（更新图片）"""
        # 如果状态没有改变，则不进行任何操作
        if self.current_state == state:
            return
            
        self.current_state = state
        
        # 处理speaking状态 - 显示WebP动画
        if state == 'speaking':
            path = STATE_IMAGES.get(state, STATE_IMAGES['idle'])
            if os.path.exists(path):
                # 隐藏静态图片标签
                self.pet_label.hide()
                
                # 设置webp_player的位置和大小（与主窗口完全重合）
                self.webp_player.setGeometry(self.rect())
                
                # 加载并播放WebP动画
                if self.webp_player.load_webp(path):
                    self.webp_player.show()
                    self.webp_player.raise_()  # 确保WebP播放器在最前面
                    self.webp_player.play()
                else:
                    # 如果加载失败，显示默认红色图片
                    self.pet_label.show()
                    pixmap = QPixmap(150, 150)
                    pixmap.fill(Qt.red)
                    # 缩放并居中显示图片
                    scaled_pixmap = pixmap.scaled(150, 150, Qt.KeepAspectRatio, Qt.SmoothTransformation)
                    self.pet_label.setPixmap(scaled_pixmap)
                    self.pet_label.resize(scaled_pixmap.width(), scaled_pixmap.height())
                    # 居中对齐
                    self.pet_label.move((self.width() - scaled_pixmap.width()) // 2,
                                       (self.height() - scaled_pixmap.height()) // 2)
            else:
                # 文件不存在，显示默认红色图片
                self.pet_label.show()
                pixmap = QPixmap(150, 150)
                pixmap.fill(Qt.red)
                # 缩放并居中显示图片
                scaled_pixmap = pixmap.scaled(150, 150, Qt.KeepAspectRatio, Qt.SmoothTransformation)
                self.pet_label.setPixmap(scaled_pixmap)
                self.pet_label.resize(scaled_pixmap.width(), scaled_pixmap.height())
                # 居中对齐
                self.pet_label.move((self.width() - scaled_pixmap.width()) // 2,
                                   (self.height() - scaled_pixmap.height()) // 2)
        else:
            # 其他状态显示静态图片
            if hasattr(self, 'webp_player'):  # 确保webp_player存在
                self.webp_player.stop()
                self.webp_player.hide()
            self.pet_label.show()
            
            # 创建默认图片（如果不存在）
            path = STATE_IMAGES.get(state, STATE_IMAGES['idle'])
            if not os.path.exists(path):
                self.create_default_image(path, state)
                
            pixmap = QPixmap(path)
            if pixmap.isNull():
                # 如果图片加载失败，创建默认图片
                pixmap = QPixmap(150, 150)
                if state == "idle":
                    pixmap.fill(Qt.green)
                elif state == "listening":
                    pixmap.fill(Qt.blue)
                elif state == "thinking":
                    pixmap.fill(Qt.yellow)
                elif state == "speaking":
                    pixmap.fill(Qt.red)
            
            # 缩放并居中显示图片
            scaled_pixmap = pixmap.scaled(150, 150, Qt.KeepAspectRatio, Qt.SmoothTransformation)
            self.pet_label.setPixmap(scaled_pixmap)
            self.pet_label.resize(scaled_pixmap.width(), scaled_pixmap.height())
            # 居中对齐
            self.pet_label.move((self.width() - scaled_pixmap.width()) // 2,
                               (self.height() - scaled_pixmap.height()) // 2)
            
        self.pet_label.adjustSize()

    def create_default_image(self, path, state):
        """创建默认状态图片"""
        # 确保目录存在
        os.makedirs(os.path.dirname(path), exist_ok=True)
        
        # 创建图片
        pixmap = QPixmap(150, 150)
        if state == "idle":
            pixmap.fill(Qt.green)
        elif state == "listening":
            pixmap.fill(Qt.blue)
        elif state == "thinking":
            pixmap.fill(Qt.yellow)
        elif state == "speaking":
            pixmap.fill(Qt.red)
        pixmap.save(path)

    def safe_set_pet_state(self, state):
        """线程安全的状态设置方法"""
        self.stateChanged.emit(state)

    def update_state(self):
        """状态更新"""
        pass

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            # 记录拖拽起始位置
            self.dragging = True
            self.old_pos = event.globalPos()

        elif event.button() == Qt.RightButton:
            # 右键关闭程序
            self.close()

    def mouseMoveEvent(self, event):
        """鼠标移动事件（用于拖动窗口）"""
        if self.dragging:
            delta = event.globalPos() - self.old_pos
            self.move(self.pos() + delta)
            self.old_pos = event.globalPos()

    def mouseReleaseEvent(self, event):
        """鼠标释放事件（用于拖动窗口）"""
        if event.button() == Qt.LeftButton:
            self.dragging = False


    def showEvent(self, event):
        """显示窗口事件"""
        super().showEvent(event)
        self.set_pet_state("idle")

    def hideEvent(self, event):
        """隐藏窗口事件"""
        super().hideEvent(event)
        # 隐藏时停止WebP播放
        if self.webp_player:
            self.webp_player.stop()
            self.webp_player.hide()

    def closeEvent(self, event):
        """关闭窗口事件（用于清理资源）"""
        # 关闭时停止WebP播放
        if self.webp_player:
            self.webp_player.stop()
            self.webp_player.hide()
        self.tray_icon.hide()
        event.accept()

    def set_state(self, state):
        """设置当前状态（从线程中调用）"""
        self.safe_set_pet_state(state)

    def resizeEvent(self, event):
        """窗口大小改变事件"""
        super().resizeEvent(event)
        # 同步调整WebP播放器的大小
        if hasattr(self, 'webp_player'):
            self.webp_player.setGeometry(self.rect())
        
        # 重新居中显示静态图片
        if self.pet_label.isVisible():
            pixmap = self.pet_label.pixmap()
            if pixmap:
                scaled_pixmap = pixmap.scaled(150, 150, Qt.KeepAspectRatio, Qt.SmoothTransformation)
                self.pet_label.resize(scaled_pixmap.width(), scaled_pixmap.height())
                self.pet_label.move((self.width() - scaled_pixmap.width()) // 2,
                                   (self.height() - scaled_pixmap.height()) // 2)

    def moveEvent(self, event):
        """窗口移动事件"""
        super().moveEvent(event)
        # 同步移动WebP播放器的位置
        if self.webp_player:
            self.webp_player.move(0, 0)  # 因为webp_player是子窗口，所以移动到(0,0)即可